package ar.uade.distribuidas.tpo.dao;

import java.io.InputStream;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.LinkedList;
import java.util.List;


import org.joda.time.LocalDate;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import ar.uade.distribuidas.tpo.base.dominiodto.ClienteDTO;
import ar.uade.distribuidas.tpo.base.dominiodto.CondicionDeVentaDTO;
import ar.uade.distribuidas.tpo.base.dominiodto.CotizacionDTO;
import ar.uade.distribuidas.tpo.base.dominiodto.ItemCotizacionDTO;
import ar.uade.distribuidas.tpo.base.dominiodto.ItemPedidoDTO;
import ar.uade.distribuidas.tpo.base.dominiodto.ItemSolicitudDeCotizacionDTO;
import ar.uade.distribuidas.tpo.base.dominiodto.OrdenDePedidoDTO;
import ar.uade.distribuidas.tpo.base.dominiodto.RodamientoDTO;
import ar.uade.distribuidas.tpo.base.utils.FormatUtils;
import ar.uade.distribuidas.tpo.web.delegado.BD;

public class OrdenDePedidoXmlDao {

	private static OrdenDePedidoXmlDao instance;

	//private Document doc;
	// private static final String FILE_NAME = "orden-de-pedido.xml";
	// Parametrizado
	private BD bd;

	public static OrdenDePedidoXmlDao getInstancia() {
		if (instance == null) {
			instance = new OrdenDePedidoXmlDao();
			//instance.createDocument(filecontent);
		}
		return instance;
	}

	private OrdenDePedidoXmlDao() {
		bd = BD.getInstance();
	}

	/*private void createDocument(InputStream filecontent) {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder;
		try {
			builder = factory.newDocumentBuilder();
			doc = builder.parse(filecontent);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}*/

	public List<OrdenDePedidoDTO> getOrdenDePedidoDTO(Document docu)
			throws MalformedURLException, RemoteException, NotBoundException {
		List<OrdenDePedidoDTO> odps = new LinkedList<>();
		NodeList nodos = docu.getElementsByTagName("OrdenDePedido");

		for (int i = 0; i < nodos.getLength(); i++) {
			if (nodos.item(i).getNodeType() == Node.ELEMENT_NODE)
				odps.add(mapOrdenDePedidoDTO((Element) nodos.item(i)));
		}

		return odps;
	}

	private OrdenDePedidoDTO mapOrdenDePedidoDTO(Element ordenDePedidoXml) {
		OrdenDePedidoDTO odp = new OrdenDePedidoDTO();

		// TODO no nos lo da el cliente
		Long numero = Long.parseLong(ordenDePedidoXml.getAttribute("numero"));
		Element fechaXml = (Element) ordenDePedidoXml.getElementsByTagName(
				"Fecha").item(0);
		LocalDate fecha = LocalDate.parse(fechaXml.getTextContent(),
				FormatUtils.DATE_FORMATTER);

		odp.setNumero(numero);
		odp.setFecha(fecha.toString(FormatUtils.DATE_FORMATTER));

		Element cdvElement = (Element) ordenDePedidoXml.getElementsByTagName(
				"CondicionesDeVenta").item(0);
		NodeList nodosCondiciones = cdvElement.getChildNodes();
		Element auxElem;
		CondicionDeVentaDTO condicion = new CondicionDeVentaDTO();
		int iter = 0;
		while (iter < nodosCondiciones.getLength()) {

			if (nodosCondiciones.item(iter).getNodeType() == Node.ELEMENT_NODE) { // Asumo
																					// que
																					// esta
																					// definido
																					// en
																					// el
																					// formato
																					// del
				Node nodo = (Node) nodosCondiciones.item(iter); // XML que el
																// primer
																// elemento de
																// "CondicionesDeVenta"
																// es un medio
																// de pago.
				auxElem = (Element) nodo;
				condicion = CondicionDeVentaXmlParser.parseCDV(auxElem);
			}
			iter++;
		}
		odp.setCondicionVenta(condicion);



		Element clienteXml = (Element) ordenDePedidoXml.getElementsByTagName(
				"Cliente").item(0);
		Long cuil = Long.parseLong(clienteXml.getElementsByTagName("Cuil")
				.item(0).getTextContent());

		ClienteDTO cliente = BD.getInstance().getCliente(cuil);

		odp.setCliente(cliente);

		Element referenciaXml = (Element) ordenDePedidoXml
				.getElementsByTagName("Referencia").item(0);
		NodeList cotizacionesXml = referenciaXml
				.getElementsByTagName("Cotizacion");

		for (int i = 0; i < cotizacionesXml.getLength(); i++) {
			Element cotizacionXml = (Element) cotizacionesXml.item(i);
			CotizacionDTO cotizacion = this.mapCotizacionDTO(cotizacionXml);

			Element rodamientoXml = (Element) cotizacionXml
					.getElementsByTagName("Rodamientos").item(0);
			NodeList itemsXml = rodamientoXml.getElementsByTagName("Item");

			List<ItemPedidoDTO> items = new LinkedList<>();


				Element cotizacion2Xml = (Element) ordenDePedidoXml
						.getElementsByTagName("Cotizacion").item(0);
				Long nume = Long.parseLong(cotizacion2Xml
						.getElementsByTagName("Numero").item(0)
						.getTextContent());

				Element rodamientoElem = (Element) ordenDePedidoXml
						.getElementsByTagName("Rodamientos").item(0);
				NodeList items2 = rodamientoElem.getElementsByTagName("Item");

				for (int k = 0; k < items2.getLength(); k++) {
					Node item = items2.item(k);
					ItemPedidoDTO itemP = new ItemPedidoDTO();
					itemP.setCotizacionId(nume);
					itemP.setItemCotizacionId(itemP.getId());
					if (item.getNodeType() == Node.ELEMENT_NODE) {
						Element it = (Element) item;
						RodamientoDTO rodDTO = BD.getInstance().getRodamiento(
								Long.parseLong(it.getAttribute("serie")),
								getValue("Sufijo", it), getValue("Marca", it),
								getValue("Origen", it));

						auxElem = (Element) it.getElementsByTagName("Cantidad")
								.item(0);
						int cantidad = Integer
								.valueOf(auxElem.getTextContent());
						itemP.setCantidad(cantidad);
						itemP.setRodamientoId(rodDTO.getIdRodamiento());
						itemP.setOrdenDePedidoId(odp.getNumero());
						items.add(itemP);
					}

				}

			

			odp.setItemsPedido(items);
		}

		return odp;
	}

	// private String quitarTildes(String original) {
	// String sinTildes = null;
	// // Normalizamos en la forma NFD (Canonical decomposition)
	// original = Normalizer.normalize(original, Normalizer.Form.NFD);
	// // Reemplaza los tildes usando una expresi�n regular de Bloque Unicode
	// sinTildes = original.replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
	//
	// return sinTildes;
	// }

	private CotizacionDTO mapCotizacionDTO(Element cotizacionXml) {
		Long idCotizacionDTO = Long.parseLong(cotizacionXml
				.getElementsByTagName("Numero").item(0).getTextContent());

		CotizacionDTO cot = null;
		cot = bd.getCotizacion(idCotizacionDTO);

		return cot;
	}

	private ItemCotizacionDTO mapItemCotizacionDTO(Element itemXml) {
		// Long nroSerie = Long.parseLong(itemXml.getAttribute("serie"));
		RodamientoDTO rodamiento = new RodamientoDTO();

		String serie = itemXml.getAttribute("serie");
		Element aux = (Element) itemXml.getElementsByTagName("Sufijo").item(0);
		String sufijo = aux.getTextContent();
		aux = (Element) itemXml.getElementsByTagName("Marca").item(0);
		String marca = aux.getTextContent();
		aux = (Element) itemXml.getElementsByTagName("Origen").item(0);
		String pais = aux.getTextContent();

		Integer cantidad = Integer.parseInt(itemXml
				.getElementsByTagName("Cantidad").item(0).getTextContent());

		rodamiento.setMarca(marca);
		rodamiento.setNroSerie(Long.parseLong(serie));
		rodamiento.setPais(pais);
		rodamiento.setSufijo(sufijo);

		ItemCotizacionDTO itemCotizacionDTO = null;

		RodamientoDTO rodT = bd.getRodamiento(rodamiento);

		if (rodT != null) {
			itemCotizacionDTO = new ItemCotizacionDTO();
			ItemSolicitudDeCotizacionDTO itemSolCotizacionDTO = new ItemSolicitudDeCotizacionDTO();

			itemSolCotizacionDTO.setRodamiento(rodT);
			itemSolCotizacionDTO.setCantidad(cantidad);
			itemSolCotizacionDTO.setCantidad(cantidad);
			//itemCotizacionDTO.setItemSolicitudId(itemSolCotizacionDTO.getId());
			
		}

		return itemCotizacionDTO;
	}

	private static String getValue(String tag, Element element) {
		NodeList nodes = element.getElementsByTagName(tag).item(0)
				.getChildNodes();
		Node node = (Node) nodes.item(0);
		if (node != null) {
			return node.getNodeValue();
		}
		return "";
	}

}
